﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Bricks.Business.Service.Impl;
using Bricks.Site.Models;
using Bricks.Business.Models.FlowProcess;
using System.Xml;
using System.Web.Script.Serialization;
using Bricks.Business.Service;
using Bricks.Component.Utils;
using System.Xml;
using System.Collections;
using Bricks.Site.Web.CommonUtils;


namespace Bricks.Site.Web.Controllers
{
    [Export]
    public class FlowOldController : BaseController
    {
        #region 导入服务
        [Import]
        public IFlowNodeService FlowNodeService { get; set; }
        [Import]
        public IBaklogTaskService BaklogTaskService { get; set; }
        [Import]
        public IFlowUtilsService FlowUtilsService { get; set; }
        [Import]
        public IFlowGraphNodeService FlowGraphNodeService { get; set; }
        [Import]
        public ICompleteFlowNodeService CompleteFlowNodeService { get; set; }
        [Import]
        public IProcessedTaskService ProcessedTaskService { get; set; }
        [Import]
        public IFlowProcessMessageService FlowProcessMessageService { get; set; }
        [Import]
        public IBaklogTaskTempService BaklogTaskTempService { get; set; }
        [Import]
        public IHolidayRequestService HolidayRequestService { get; set; }
        [Import]
        public IAlterService AlterService { get; set; }
        #endregion

        #region 流转
        /// <summary>
        /// 流转界面的Action：将单据的状态值赋值给CirculationBackView，作为流转视图的Model
        /// </summary>
        /// <param name="flowCode">流程的Code</param>
        /// <param name="recordID">实际单据的ID</param>
        /// <param name="handleState">单据的状态</param>
        /// <returns></returns>
        public ActionResult CirculationFlow(string flowCode, string recordID, string handleState)
        {
            FlowRecordView circulationView = new FlowRecordView();
            circulationView.RecordID = recordID;
            circulationView.FlowCode = flowCode;
            circulationView.HandleState = handleState;

            string currentFlowNodeCode = string.Empty;
            string nodeXML = string.Empty;
            if (handleState == "0")
            {
                FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, true, "");
                currentFlowNodeCode = flowNodeView.NodeCode;
                nodeXML = flowNodeView.NodeXML;
            }
            else
            {
                currentFlowNodeCode = BaklogTaskService.GetBaklogTask(User.Identity.Name, recordID)[0].CurrentFlowNodeCode;
                nodeXML = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, currentFlowNodeCode).NodeXML;
            }
            circulationView.CurrentFlowNodeCode = currentFlowNodeCode;

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(nodeXML);
            XmlNode personConditionNode = doc.SelectSingleNode("NodeXML/defaultProcessPerson/condition");
            if (personConditionNode != null)
            {
                circulationView.ProcessPersonCondition = personConditionNode.InnerText;
            }
            return View(circulationView);
        }

        /// <summary>
        /// 流转节点列表的获取函数
        /// </summary>
        /// <param name="flowCode">流程的Code</param>
        /// <param name="recordID">实际单据的ID</param>
        /// <param name="handleState">单据的状态</param>
        /// <returns></returns>
        public ActionResult SetFlowCirculationData(string flowCode, string recordID, string handleState)
        {
            //获取当前节点的XML里面配置的流转节点Code字符串
            string nodeXML = string.Empty;
            if (handleState == "0")
            {
                FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, true, "");
                nodeXML = flowNodeView.NodeXML;
            }
            else
            {
                string currentProcessNodeCode = BaklogTaskService.GetBaklogTask(User.Identity.Name, recordID)[0].CurrentFlowNodeCode;
                nodeXML = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, currentProcessNodeCode).NodeXML;
            }
            string[] arrFlowNodeCode = GetNodeCodeByXMLForCirculation(nodeXML, recordID);

            //分解Code字符串，遇到条件节点继续往下找，找出最终的流转节点
            List<FlowNodeView> lstCirculationFlowNode = new List<FlowNodeView>();
            foreach (string flowNodeCode in arrFlowNodeCode)
            {
                GetCirculationOrConditionNode(flowCode, flowNodeCode, recordID, flowNodeCode, lstCirculationFlowNode);
            }

            foreach (FlowNodeView flowNodeView in lstCirculationFlowNode)
            {
                flowNodeView.NodeXML = "";
            }
            return Json(lstCirculationFlowNode, JsonRequestBehavior.AllowGet);
        }

        private string[] GetNodeCodeByXMLForCirculation(string nodeXML, string recordID)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(nodeXML);
            XmlNodeList nodeList = doc.SelectNodes("NodeXML/circulationCell");
            string getType = nodeList[0].SelectSingleNode("getType").InnerText;
            string processNodeCode = string.Empty;
            if (getType.ToLower() == "value")
            {
                processNodeCode = nodeList[0].SelectSingleNode("cellsName").InnerText;
            }
            else
            {
                string functionName = nodeList[0].SelectSingleNode("functionName").InnerText;
                Hashtable para = new Hashtable();
                para.Add("RecordID", recordID);
                XmlNode paraNode = nodeList[0].SelectSingleNode("functionParam");
                if (paraNode != null)
                {
                    para.Add(paraNode.Name, paraNode.InnerText);
                }
                processNodeCode = FlowUtilsService.ExecuteCommand(functionName, para) as string;
            }
            return processNodeCode.Split(',');
        }

        private void GetCirculationOrConditionNode(string flowCode, string flowNodeCode, string recordID, string theFirstLevelCirculationNodeCode, List<FlowNodeView> lstFlowNode, bool isAddConditionNode = false)
        {
            FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, flowNodeCode);
            if (flowNodeView.NodeType == 2)
            {
                if (isAddConditionNode)
                {
                    lstFlowNode.Add(flowNodeView);
                }
                //如果是条件节点，获取条件节点的XML数据并解析，递归调用
                string[] arrFlowNodeCode = GetNodeCodeByXMLForCirculation(flowNodeView.NodeXML, recordID);
                foreach (string nextNodeCode in arrFlowNodeCode)
                {
                    GetCirculationOrConditionNode(flowCode, nextNodeCode, recordID, theFirstLevelCirculationNodeCode, lstFlowNode, isAddConditionNode);
                }
            }
            else
            {
                if (!isAddConditionNode)
                {
                    //不是条件的就往流转节点列表添加数据
                    if (!string.IsNullOrEmpty(flowNodeView.NodeXML))
                    {
                        XmlDocument docPerson = new XmlDocument();
                        docPerson.LoadXml(flowNodeView.NodeXML);
                        flowNodeView.DefaultProcessPerson = GetDefaultProcessPerson(docPerson, recordID);
                    }
                    flowNodeView.TheFirstLevelCirculationNodeCode = theFirstLevelCirculationNodeCode;
                }
                lstFlowNode.Add(flowNodeView);
            }
        }

        private string GetDefaultProcessPerson(XmlDocument docPerson, string recordID)
        {
            string defaultProcessPerson = string.Empty;
            XmlNode personNode = docPerson.SelectSingleNode("NodeXML/defaultProcessPerson");
            if (personNode != null)
            {
                string processPersonGetType = personNode.SelectSingleNode("getType").InnerText;
                if (processPersonGetType == "value")
                {
                    defaultProcessPerson = personNode.SelectSingleNode("presonList").InnerText;
                }
                else
                {
                    string functionName = personNode.SelectSingleNode("functionName").InnerText;
                    Hashtable para = new Hashtable();
                    para.Add("RecordID", recordID);
                    XmlNode paraNode = personNode.SelectSingleNode("functionParam");
                    if (paraNode != null)
                    {
                        para.Add(paraNode.Name, paraNode.InnerText);
                    }
                    defaultProcessPerson = FlowUtilsService.ExecuteCommand(functionName, para) as string;
                }
            }
            return defaultProcessPerson;
        }

        [HttpPost]
        public ActionResult SaveCirculationData(FlowRecordView model, string circulationNodeListJson, string approvalOpinion)
        {
            try
            {
                //转换流转节点成XML,更新单据的状态，获取申请人
                XmlNodeList circulationNodeList = XMLJsonUtils.JsonToXml(circulationNodeListJson).SelectNodes("root/rows/Item");
                string firstCirculationNodeCode = circulationNodeList[0].SelectSingleNode("NodeCode").InnerText;
                string requestPerson = UpdateReceiptForCirculation(model, firstCirculationNodeCode);

                //判断是否申请节点，获取当前节点信息
                bool isRequestNode = false;
                if (model.HandleState == "0")
                {
                    isRequestNode = true;
                }
                FlowNodeView currentFlowNodeView = FlowNodeService.GetFlowNodeByNodeCode(model.FlowCode, isRequestNode, model.CurrentFlowNodeCode);

                //初始化存放到达流转节点之前经过的所有节点的Dictionary,拼接流转节点的Code,并处理当前节点
                Dictionary<string, List<FlowNodeView>> conditionNodeInfo = new Dictionary<string, List<FlowNodeView>>();
                string circulationNodeStr = string.Empty;
                foreach (XmlNode circulationNode in circulationNodeList)
                {
                    string theFirstLevelCirculationNodeCode = circulationNode.SelectSingleNode("TheFirstLevelCirculationNodeCode").InnerText;
                    circulationNodeStr += circulationNode.SelectSingleNode("NodeCode").InnerText + ",";
                    conditionNodeInfo.Add(theFirstLevelCirculationNodeCode, new List<FlowNodeView>());
                }
                circulationNodeStr=circulationNodeStr.Trim(',');
                List<CompleteFlowNodeView> addCompleteFlowNodeList = CompleteFlowNodeService.GetCompleteFlowNode(model.RecordID);
                bool isCompleteCurrentNode = ProcessCurrentNodeForCirculation(isRequestNode, addCompleteFlowNodeList, model, currentFlowNodeView, approvalOpinion, circulationNodeStr);

                //判断当前节点是否需要生成待办信息
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(currentFlowNodeView.NodeXML);
                bool isGenerateBaklogTask = true;
                XmlNode addBaklogTaskCondition = doc.SelectSingleNode("NodeXML/circulationCell/addBaklogTaskCondition");
                XmlNode baklogTaskConditionExceCondition = doc.SelectSingleNode("NodeXML/circulationCell/addBaklogTaskCondition/execCondition");
                if (addBaklogTaskCondition != null && (baklogTaskConditionExceCondition == null || (baklogTaskConditionExceCondition != null && baklogTaskConditionExceCondition.InnerText == circulationNodeStr)))
                {
                    //如果判断是否生成待办节点不为空，判断是否生成待办的执行条件节点为空
                    //或者判断是否生成待办节点不为空，判断是否生成待办的执行条件节点不为空并且执行条件的值与当前流转节点列表相等的时候
                    //执行判断是否生成待办节点函数，获取是否需要
                    string functionName = addBaklogTaskCondition.SelectSingleNode("functionName").InnerText;
                    Hashtable para = new Hashtable();
                    para.Add("RecordID", model.RecordID);
                    XmlNode paraNode = addBaklogTaskCondition.SelectSingleNode("functionParam");
                    if (paraNode != null)
                    {
                        para.Add(paraNode.Name, paraNode.InnerText);
                    }
                    isGenerateBaklogTask = Convert.ToBoolean(FlowUtilsService.ExecuteCommand(functionName, para));
                }

                //获取条件和流转节点并添加到流程图构造表
                List<FlowGraphNodeView> addFlowGraphNodeViewList = FlowGraphNodeService.GetFlowGraphNode(model.RecordID);
                GetPassConditionNode(model, doc, conditionNodeInfo);
                foreach (List<FlowNodeView> nodeList in conditionNodeInfo.Values)
                {
                    for (int i = 0; i < nodeList.Count; i++)
                    {
                        bool isAdd = true;
                        if ((i == nodeList.Count - 1) && !isCompleteCurrentNode)
                        {
                            isAdd = false;
                        }
                        if (isAdd)
                        {
                            int orderNo = 0;
                            FlowGraphNodeView firstFlowGraphNodeView = addFlowGraphNodeViewList.OrderByDescending(f => f.OrderNo).FirstOrDefault();
                            if (firstFlowGraphNodeView != null)
                            {
                                orderNo = firstFlowGraphNodeView.OrderNo;
                            }
                            string pathStartNodeCode = model.CurrentFlowNodeCode;
                            if (i > 0)
                            {
                                pathStartNodeCode = nodeList[i - 1].NodeCode;
                            }
                            addFlowGraphNodeViewList.Add(new FlowGraphNodeView()
                            {
                                ID = Guid.NewGuid(),
                                RecordID = model.RecordID,
                                PathStartNodeCode = pathStartNodeCode,
                                PathEndNodeCode = nodeList[i].NodeCode,
                                OrderNo = orderNo + 1,
                                NodeType = nodeList[i].NodeType,
                                ActionType = 0
                            });
                        }

                        //添加条件完成节点
                        if (i < nodeList.Count - 1)
                        {
                            string preNodeCode = string.Empty;
                            XmlDocument docConditionNode = new XmlDocument();
                            doc.LoadXml(nodeList[i].NodeXML);
                            XmlNode preNodeList = doc.SelectSingleNode("NodeXML/preCell/cellList");
                            string[] nodeCodeArr = preNodeList.InnerText.Split(',');
                            foreach (string code in nodeCodeArr)
                            {
                                CompleteFlowNodeView completeFlowNodeView = addCompleteFlowNodeList.SingleOrDefault(c => c.NodeCode == code);
                                if (completeFlowNodeView != null)
                                {
                                    preNodeCode = completeFlowNodeView.NodeCode;
                                }
                            }

                            string parentNodeCode = "";
                            XmlNode parentNode = doc.SelectSingleNode("NodeXML/parentCell");
                            if (parentNode != null)
                            {
                                parentNodeCode = parentNode.InnerText;
                            }

                            addCompleteFlowNodeList.Add(new CompleteFlowNodeView()
                            {
                                ID = GuidHelper.NewGuid(),
                                RecordID = model.RecordID,
                                NodeCode = nodeList[i].NodeCode,
                                NodeName = nodeList[i].NodeName,
                                NodeProcessDepartmentPerson = "",
                                PreNodeCode = preNodeCode,
                                ParentNodeCode = parentNodeCode,
                                NodeLevel = nodeList[i].NodeLevel,
                                NodeType = nodeList[i].NodeType,
                                NodeSubType = nodeList[i].NodeSubType,
                                SpecState = 0
                            });
                        }
                    }
                }
                FlowGraphNodeService.AddFlowGraphNode(addFlowGraphNodeViewList);
                CompleteFlowNodeService.InsetCompleteFlowNode(addCompleteFlowNodeList);

                //删除待办,如果是传阅节点添加传阅信息，添加待办
                if (isCompleteCurrentNode && isGenerateBaklogTask)
                {
                    int nodelLevel = Convert.ToInt32(circulationNodeList[0].SelectSingleNode("NodeLevel").InnerText);
                    //删除待办
                    List<BaklogTaskView> originalBaklogTaskList = BaklogTaskService.GetBaklogTaskByRecordID(model.RecordID);
                    List<BaklogTaskView> deleteBaklogTaskNewList = new List<BaklogTaskView>();
                    XmlNode deleteCurrentNodeBaklogTaskCondition = doc.SelectSingleNode("NodeXML/circulationCell/deleteCurrentNodeBaklogTaskCondition");
                    if (deleteCurrentNodeBaklogTaskCondition != null && deleteCurrentNodeBaklogTaskCondition.InnerText == circulationNodeStr)
                    {
                        IEnumerable<BaklogTaskView> deleteList = originalBaklogTaskList.Where(b => b.CurrentFlowNodeCode == model.CurrentFlowNodeCode);
                        foreach (BaklogTaskView baklogTaskView in deleteList)
                        {
                            deleteBaklogTaskNewList.Add(baklogTaskView);
                        }
                    }
                    else
                    {
                        foreach (BaklogTaskView baklogTaskView in originalBaklogTaskList)
                        {
                            if (baklogTaskView.NodeLevel == nodelLevel)
                            {
                                deleteBaklogTaskNewList.Add(baklogTaskView);
                            }
                        }
                    }
                    BaklogTaskService.DeleteBaklogTask(deleteBaklogTaskNewList);

                    //如果是传阅节点添加流程传阅消息
                    //AddFlowProcessMessageForCirculation(doc, model);

                    //添加待办
                    if (firstCirculationNodeCode != "End")
                    {
                        foreach (XmlNode circulationNode in circulationNodeList)
                        {
                            string circulationNodeCode = circulationNode.SelectSingleNode("NodeCode").InnerText;
                            AddBaklogTaskForCirculation(model, circulationNodeCode, nodelLevel, requestPerson, 0);
                        }
                    }
                }

                return Content("Success");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }

        /// <summary>
        /// 更新单据的状态，获取申请人
        /// </summary>
        /// <param name="model">流转视图的Model</param>
        /// <param name="nodeCode">第一个流转节点的Code</param>
        private string UpdateReceiptForCirculation(FlowRecordView model, string nodeCode)
        {
            string requestPerson = string.Empty;
            switch (model.FlowCode)
            {
                case "HolidayRequest":
                    HolidayRequestView holidayRequestView = HolidayRequestService.GetHolidayRequestByID(model.RecordID);
                    requestPerson = holidayRequestView.RequestPerson;
                    if (holidayRequestView.HandleState == "0")
                    {
                        HolidayRequestService.UpdateHoliday(Guid.Parse(model.RecordID), "", DateTime.Now, DateTime.Now, "1", true);
                    }
                    if (nodeCode == "End")
                    {
                        HolidayRequestService.UpdateHoliday(Guid.Parse(model.RecordID), "", DateTime.Now, DateTime.Now, "2", true);
                    }
                    break;
                case "Alter":
                    AlterView alterView = AlterService.GetAlterByID(model.RecordID);
                    requestPerson = alterView.RequestPerson;
                    if (alterView.HandleState == "0")
                    {
                        alterView.HandleState = "1";
                        AlterService.SaveAlter(alterView);
                    }
                    if (nodeCode == "End")
                    {
                        alterView.HandleState = "2";
                        AlterService.SaveAlter(alterView);
                    }
                    break;
            }
            return requestPerson;
        }

        /// <summary>
        /// 如果是申请节点：将申请节点更新为已完成状态，将申请节点添加到已办表，将申请节点添加到流程图构造表
        /// 如果不是申请节点：根据当前节点的处理人之间的条件关系来分支；
        ///                   如果是and的关系，找到当前处理人所在的待办记录，将其添加到已办表并删除
        ///                   如果是空或者是or的关系，找到当前处理人所在的待办记录，将其添加到已办表并删除当前节点的所有待办
        ///                   最后判断当前节点在待办里面还有没有记录，没有的话就将当前的状态标记为已完成
        /// </summary>
        /// <param name="isRequestNode">是否是申请节点</param>
        /// <param name="model">流转的model</param>
        /// <param name="nodeName">当前节点的名称</param>
        /// <param name="approvalOpinion">审批意见</param>
        private bool ProcessCurrentNodeForCirculation(bool isRequestNode, List<CompleteFlowNodeView> addCompleteFlowNodeList, FlowRecordView model, FlowNodeView currentFlowNodeView, string approvalOpinion, string circulationNodeStr)
        {
            bool isComplete = false;
            List<ProcessedTaskView> addProcessedTaskList = new List<ProcessedTaskView>();
            List<BaklogTaskView> deleteBaklogTaskList = new List<BaklogTaskView>();
            if (isRequestNode)
            {
                addCompleteFlowNodeList.Add(new CompleteFlowNodeView()
                {
                    ID = Guid.NewGuid(),
                    RecordID = model.RecordID,
                    NodeCode = model.CurrentFlowNodeCode,
                    NodeName = currentFlowNodeView.NodeName,
                    NodeProcessDepartmentPerson = DepartmentPersonUtils.GetDepartmentByUser(User.Identity.Name) + "|" + User.Identity.Name,
                    PreNodeCode = "",
                    ParentNodeCode = "",
                    NodeLevel = currentFlowNodeView.NodeLevel,
                    NodeType = currentFlowNodeView.NodeType,
                    NodeSubType = currentFlowNodeView.NodeSubType,
                    SpecState = 0
                });
                isComplete = true;

                addProcessedTaskList.Add(new ProcessedTaskView()
                {
                    ID = Guid.NewGuid(),
                    RecordID = model.RecordID,
                    CurrentProcessNodeCode = model.CurrentFlowNodeCode,
                    CurrentProcessNodeName = currentFlowNodeView.NodeName,
                    ApprovalOpinion = approvalOpinion,
                    CurrentProcessPersonDepartment = DepartmentPersonUtils.GetDepartmentByUser(User.Identity.Name),
                    CurrentProcessPerson = User.Identity.Name,
                    ProcessTime = DateTime.Now
                });
            }
            else
            {
                List<BaklogTaskView> originalBaklogTaskList = BaklogTaskService.GetBaklogTaskByNodeCode(model.CurrentFlowNodeCode, model.RecordID);
                List<BaklogTaskTempView> baklogTaskTempList = BaklogTaskTempService.GetBaklogTaskTempByNodeCode(model.CurrentFlowNodeCode, model.RecordID);
                if (!string.IsNullOrEmpty(model.ProcessPersonCondition) && model.ProcessPersonCondition.ToLower() == "and")
                {
                    BaklogTaskView deleteInfo = originalBaklogTaskList.Find(b => b.CurrentProcessPerson == User.Identity.Name);
                    deleteBaklogTaskList.Add(deleteInfo);

                    addProcessedTaskList.Add(new ProcessedTaskView()
                    {
                        ID = Guid.NewGuid(),
                        RecordID = model.RecordID,
                        CurrentProcessNodeCode = model.CurrentFlowNodeCode,
                        CurrentProcessNodeName = currentFlowNodeView.NodeName,
                        ApprovalOpinion = approvalOpinion,
                        CurrentProcessPersonDepartment = deleteInfo.CurrentProcessPersonDepartment,
                        CurrentProcessPerson = deleteInfo.CurrentProcessPerson,
                        ProcessTime = DateTime.Now
                    });

                    baklogTaskTempList.Add(new BaklogTaskTempView()
                    {
                        ID = deleteInfo.ID,
                        RecordID = deleteInfo.RecordID,
                        CurrentFlowNodeCode = deleteInfo.CurrentFlowNodeCode,
                        CurrentProcessPersonDepartment = deleteInfo.CurrentProcessPersonDepartment,
                        CurrentProcessPerson = deleteInfo.CurrentProcessPerson
                    });
                }
                else
                {
                    foreach (BaklogTaskView baklogTaskView in originalBaklogTaskList)
                    {
                        deleteBaklogTaskList.Add(baklogTaskView);

                        if (baklogTaskView.CurrentProcessPerson == User.Identity.Name)
                        {
                            ProcessedTaskView processedTask = new ProcessedTaskView()
                            {
                                ID = Guid.NewGuid(),
                                RecordID = model.RecordID,
                                CurrentProcessNodeCode = model.CurrentFlowNodeCode,
                                CurrentProcessNodeName = currentFlowNodeView.NodeName,
                                ApprovalOpinion = approvalOpinion,
                                CurrentProcessPersonDepartment = baklogTaskView.CurrentProcessPersonDepartment,
                                CurrentProcessPerson = baklogTaskView.CurrentProcessPerson,
                                ProcessTime = DateTime.Now
                            };
                            addProcessedTaskList.Add(processedTask);
                        }

                        baklogTaskTempList.Add(new BaklogTaskTempView()
                        {
                            ID = baklogTaskView.ID,
                            RecordID = baklogTaskView.RecordID,
                            CurrentFlowNodeCode = baklogTaskView.CurrentFlowNodeCode,
                            CurrentProcessPersonDepartment = baklogTaskView.CurrentProcessPersonDepartment,
                            CurrentProcessPerson = baklogTaskView.CurrentProcessPerson
                        });
                    }
                }

                BaklogTaskTempService.AddBaklogTaskTemp(baklogTaskTempList);
                BaklogTaskService.DeleteBaklogTask(deleteBaklogTaskList);
                originalBaklogTaskList = BaklogTaskService.GetBaklogTaskByNodeCode(model.CurrentFlowNodeCode, model.RecordID);
                if (originalBaklogTaskList.Count() == 0)
                {
                    AddCompleteFlowNodeForCurrentNode(currentFlowNodeView, circulationNodeStr, baklogTaskTempList, addCompleteFlowNodeList, model.RecordID, model.CurrentFlowNodeCode);
                    BaklogTaskTempService.DeleteBaklogTaskTemp(baklogTaskTempList);
                    isComplete = true;
                }
            }
            CompleteFlowNodeService.InsetCompleteFlowNode(addCompleteFlowNodeList);
            ProcessedTaskService.AddProcessedTask(addProcessedTaskList);
            return isComplete;
        }

        private void AddCompleteFlowNodeForCurrentNode(FlowNodeView currentFlowNodeView, string circulationNodeStr, List<BaklogTaskTempView> baklogTaskTempList, List<CompleteFlowNodeView> addCompleteFlowNodeList, string recordID, string nodeCode)
        {
            int specState = 0;
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(currentFlowNodeView.NodeXML);
            XmlNode isCompleteNode = doc.SelectSingleNode("NodeXML/isComplete");
            if (isCompleteNode != null && isCompleteNode.InnerText != circulationNodeStr)
            {
                specState = 1;
            }

            string nodeProcessDepartmentPerson = string.Empty;
            if (baklogTaskTempList != null)
            {
                foreach (BaklogTaskTempView baklogTaskTempView in baklogTaskTempList)
                {
                    nodeProcessDepartmentPerson += baklogTaskTempView.CurrentProcessPersonDepartment + "|" + baklogTaskTempView.CurrentProcessPerson + ",";
                }
            }

            string preNodeCode = string.Empty;
            XmlNode preNodeList = doc.SelectSingleNode("NodeXML/preCell/cellList");
            XmlNode preNodeCondition = doc.SelectSingleNode("NodeXML/preCell/condition");
            if (preNodeCondition != null && preNodeCondition.InnerText.ToLower() == "and")
            {
                preNodeCode = preNodeList.InnerText;
            }
            else
            {
                string[] nodeCodeArr = preNodeList.InnerText.Split(',');
                foreach (string code in nodeCodeArr)
                {
                    CompleteFlowNodeView completeFlowNodeView = addCompleteFlowNodeList.SingleOrDefault(c => c.NodeCode == code);
                    if (completeFlowNodeView != null)
                    {
                        preNodeCode = completeFlowNodeView.NodeCode;
                    }
                }
            }

            string parentNodeCode = "";
            XmlNode parentNode = doc.SelectSingleNode("NodeXML/parentCell");
            if (parentNode != null)
            {
                parentNodeCode = parentNode.InnerText;
            }

            //如果是分发节点，并且是从子节点返回的时候，分发节点的是真正的完成，只需要更新即可
            if (isCompleteNode != null && isCompleteNode.InnerText == circulationNodeStr)
            {
                List<CompleteFlowNodeView> existsCompleteFlowNodeViewList = CompleteFlowNodeService.GetCompleteFlowNodeByNodeCode(recordID,nodeCode);
                foreach (CompleteFlowNodeView completeFlowNodeView in existsCompleteFlowNodeViewList)
                {
                    completeFlowNodeView.SpecState = 0;
                }
                CompleteFlowNodeService.UpdateCompleteFlowNode(existsCompleteFlowNodeViewList);
            }
            else
            {
                addCompleteFlowNodeList.Add(new CompleteFlowNodeView()
                {
                    ID = GuidHelper.NewGuid(),
                    RecordID = recordID,
                    NodeCode = nodeCode,
                    NodeName = currentFlowNodeView.NodeName,
                    NodeProcessDepartmentPerson = nodeProcessDepartmentPerson.Trim(','),
                    PreNodeCode = preNodeCode,
                    ParentNodeCode = parentNodeCode,
                    NodeLevel = currentFlowNodeView.NodeLevel,
                    NodeType = currentFlowNodeView.NodeType,
                    NodeSubType = currentFlowNodeView.NodeSubType,
                    SpecState = specState
                });
            }
        }

        /// <summary>
        /// 获取流转节点经过的条件节点信息
        /// </summary>
        /// <param name="model">流转视图的Model</param>
        /// <param name="doc">当前节点的XML文档</param>
        /// <param name="conditionNodeInfo">存储流转节点经过的条件节点的字典</param>
        private void GetPassConditionNode(FlowRecordView model, XmlDocument doc, Dictionary<string, List<FlowNodeView>> conditionNodeInfo)
        {
            //解析当前节点的XML信息，获取第一批流转节点
            XmlNodeList nodeList = doc.SelectNodes("NodeXML/circulationCell");
            string getType = nodeList[0].SelectSingleNode("getType").InnerText;
            string processNodeCode = string.Empty;
            if (getType.ToLower() == "value")
            {
                processNodeCode = nodeList[0].SelectSingleNode("cellsName").InnerText;
            }
            else
            {
                string functionName = nodeList[0].SelectSingleNode("functionName").InnerText;
                Hashtable para = new Hashtable();
                para.Add("RecordID", model.RecordID);
                XmlNode paraNode = nodeList[0].SelectSingleNode("functionParam");
                if (paraNode != null)
                {
                    para.Add(paraNode.Name, paraNode.InnerText);
                }
                processNodeCode = FlowUtilsService.ExecuteCommand(functionName, para) as string;
            }

            //获取流转节点经过的条件节点
            string[] arrFlowNodeCode = processNodeCode.Split(',');
            foreach (string flowNodeCode in arrFlowNodeCode)
            {
                GetCirculationOrConditionNode(model.FlowCode, flowNodeCode, model.RecordID, flowNodeCode, conditionNodeInfo[flowNodeCode], true);
            }
        }

        private void AddBaklogTaskForCirculation(FlowRecordView model, string nodeCode, int nodelLevel, string requestPerson, int baklogType)
        {
            List<BaklogTaskView> addList = new List<BaklogTaskView>();
            FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(model.FlowCode, false, nodeCode);
            XmlDocument docPerson = new XmlDocument();
            docPerson.LoadXml(flowNodeView.NodeXML);
            string[] processDepartmentAndPersonArr = GetDefaultProcessPerson(docPerson, model.RecordID).Split(',');
            foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
            {
                string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');
                BaklogTaskView add = new BaklogTaskView();
                add.ID = GuidHelper.NewGuid();
                add.RecordID = model.RecordID;
                switch (model.FlowCode)
                {
                    case "HolidayRequest":
                        add.TaskName = "请假单";
                        break;
                    case "Alter":
                        add.TaskName = "过程管理";
                        break;
                }
                add.TaskType = model.FlowCode;
                add.RequestPerson = requestPerson;
                add.CurrentFlowNodeCode = nodeCode;
                add.CurrentProcessPersonDepartment = subProcessDepartmentAndPersonArr[0];
                add.CurrentProcessPerson = subProcessDepartmentAndPersonArr[1];
                add.NodeLevel = nodelLevel;
                addList.Add(add);
            }
            BaklogTaskService.AddBaklogTask(addList);
        }
        #endregion

        #region 回退
        /// <summary>
        /// 回退界面的Action：将单据的状态值赋值给CirculationBackView，作为回退视图的Model
        /// </summary>
        /// <param name="flowCode"></param>
        /// <param name="recordID"></param>
        /// <returns></returns>
        public ActionResult BackFlow(string flowCode, string recordID)
        {
            FlowRecordView backView = new FlowRecordView();
            backView.RecordID = recordID;
            backView.FlowCode = flowCode;
            backView.CurrentFlowNodeCode = BaklogTaskService.GetBaklogTask(User.Identity.Name, recordID)[0].CurrentFlowNodeCode;
            return View(backView);
        }

        public ActionResult SetFlowBackData(string flowCode, string recordID, string currentProcessNodeCode)
        {
            return Json(GetBackNodeList(flowCode, recordID, currentProcessNodeCode,true,false), JsonRequestBehavior.AllowGet);
        }

        private List<CompleteFlowNodeView> GetBackNodeList(string flowCode, string recordID, string currentProcessNodeCode, bool isContrainParent = true,bool isDesc=true)
        {
            FlowNodeView currentFlowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, currentProcessNodeCode);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(currentFlowNodeView.NodeXML);
            string parentNodeCode = "";
            XmlNode parentNode = doc.SelectSingleNode("NodeXML/parentCell");
            if (parentNode != null)
            {
                parentNodeCode = parentNode.InnerText;
            }
            return CompleteFlowNodeService.GetCompleteFlowNodeByParentNodeCode(recordID, parentNodeCode, isContrainParent, isDesc);
        }

        [HttpPost]
        public ActionResult SaveBackData(FlowRecordView model, string backNodeListJson, string approvalOpinion)
        {
            try
            {
                //转换回退节点成XML,获取要回退节点信息，更新单据的状态，获取申请人
                backNodeListJson = "{\"rows\":" + backNodeListJson + "}";
                XmlNodeList selectBackNodeList = XMLJsonUtils.JsonToXml(backNodeListJson).SelectNodes("root/rows/Item");
                string backNodeCode = selectBackNodeList[0].SelectSingleNode("NodeCode").InnerText;
                FlowNodeView backFlowNodeView = FlowNodeService.GetFlowNodeByNodeCode(model.FlowCode, false, backNodeCode);
                bool isRequestNode = false;
                if (backFlowNodeView.NodeType == 1)
                {
                    isRequestNode = true;
                }
                string requestPerson = UpdateReceiptForBack(model, isRequestNode);

                //处理当前节点:删待办，加已办
                FlowNodeView currentFlowNodeView = FlowNodeService.GetFlowNodeByNodeCode(model.FlowCode, false, model.CurrentFlowNodeCode);
                ProcessCurrentNodeForBack(model, approvalOpinion, currentFlowNodeView);

                //添加待办
                AddBaklogTaskForBack(isRequestNode, selectBackNodeList, model, requestPerson, backNodeCode);

                //分析要回退的节点信息，获取and关系的并行节点
                string excludeNodeCodeStr = string.Empty;
                XmlDocument docBack = new System.Xml.XmlDocument();
                docBack.LoadXml(backFlowNodeView.NodeXML);
                XmlNode brotherNode = docBack.SelectSingleNode("NodeXML/brotherCell/cellList");
                if (brotherNode != null)
                {
                    excludeNodeCodeStr = brotherNode.InnerText;
                }
                string[] excludeNodeCodeArr = excludeNodeCodeStr.Split(',');

                //在获取回退经过的节点，必须把有and关系的兄弟节点排除掉
                List<CompleteFlowNodeView> backNodeList = GetBackNodeList(model.FlowCode, model.RecordID, model.CurrentFlowNodeCode);
                List<CompleteFlowNodeView> backPassCodeList = new List<CompleteFlowNodeView>();
                foreach (CompleteFlowNodeView completeFlowNodeView in backNodeList)
                {
                    if (!excludeNodeCodeArr.Contains(completeFlowNodeView.NodeCode))
                    {
                        backPassCodeList.Add(completeFlowNodeView);
                    }
                    if (completeFlowNodeView.NodeCode == backNodeCode)
                    {
                        break;
                    }
                }

                //给中间节点发回退消息
                int actionType = AddFlowProcessMessage(backPassCodeList, model.FlowCode, backNodeCode);

                //构造回退流程写入流程节点表
                List<BackPath> lstBackPath = new List<BackPath>();
                XmlDocument docCurrent = new System.Xml.XmlDocument();
                docCurrent.LoadXml(currentFlowNodeView.NodeXML);
                XmlNode preNode = docCurrent.SelectSingleNode("NodeXML/preCell/cellList");
                string[] preCellArr = preNode.InnerText.Split(',');
                foreach (string preCellCode in preCellArr)
                {
                    CompleteFlowNodeView selectCompleteFlowNodeView = backPassCodeList.SingleOrDefault(b => b.NodeCode == preCellCode);
                    if (selectCompleteFlowNodeView != null)
                    {
                        lstBackPath.Add(new BackPath() { PathStartNodeCode = selectCompleteFlowNodeView.NodeCode, PathEndNodeCode = currentFlowNodeView.NodeCode, OrderNo = lstBackPath.Count + 1, NodeType = selectCompleteFlowNodeView.NodeType });
                        AddBackPath(selectCompleteFlowNodeView.PreNodeCode, backPassCodeList, lstBackPath, selectCompleteFlowNodeView.NodeCode);
                    }
                }
                lstBackPath=lstBackPath.OrderByDescending(b => b.OrderNo).ToList();
                List<FlowGraphNodeView> addFlowGraphNodeViewList = FlowGraphNodeService.GetFlowGraphNode(model.RecordID);
                foreach (BackPath backPath in lstBackPath)
                {
                    int orderNo = 0;
                    FlowGraphNodeView firstFlowGraphNodeView = addFlowGraphNodeViewList.OrderByDescending(f => f.OrderNo).FirstOrDefault();
                    if (firstFlowGraphNodeView != null)
                    {
                        orderNo = firstFlowGraphNodeView.OrderNo;
                    }
                    addFlowGraphNodeViewList.Add(new FlowGraphNodeView()
                    {
                        ID = Guid.NewGuid(),
                        RecordID = model.RecordID,
                        PathStartNodeCode = backPath.PathStartNodeCode,
                        PathEndNodeCode = backPath.PathEndNodeCode,
                        OrderNo = orderNo + 1,
                        NodeType = backPath.NodeType,
                        ActionType = actionType
                    });
                }
                FlowGraphNodeService.AddFlowGraphNode(addFlowGraphNodeViewList);

                //回退之后再节点完成表里面有些数据需要清除
                //回退到的那个节点删除回退节点，经过的节点删除经过节点以及经过节点的子流程节点
                //回退之后，那些要删除的节点的催办消息要删除
                List<CompleteFlowNodeView> deleteCompleteFlowNodeViewList = new List<CompleteFlowNodeView>();
                string flowCodeStr =string.Empty;
                foreach (CompleteFlowNodeView completeFlowNodeView in backPassCodeList)
                {
                    if (!deleteCompleteFlowNodeViewList.Contains(completeFlowNodeView))
                    {
                        deleteCompleteFlowNodeViewList.Add(completeFlowNodeView);
                        flowCodeStr += "'" + completeFlowNodeView.NodeCode + "',";
                    }
                    if (completeFlowNodeView.NodeCode != backNodeCode)
                    {
                        AddSubDeleteCompleteFlowNode(model, completeFlowNodeView.NodeCode, deleteCompleteFlowNodeViewList,ref flowCodeStr);
                    }
                }
                CompleteFlowNodeService.DeleteCompleteFlowNode(deleteCompleteFlowNodeViewList);
                if (flowCodeStr != "'")
                {
                    flowCodeStr = flowCodeStr.TrimEnd(',');
                    FlowProcessMessageService.ProcessFlowProcessMessageForBack(model.RecordID, flowCodeStr);
                }

                return Content("Success");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }

        /// <summary>
        /// 更新单据的状态，获取申请人
        /// </summary>
        /// <param name="model">流转视图的Model</param>
        /// <param name="nodeCode">第一个流转节点的Code</param>
        private string UpdateReceiptForBack(FlowRecordView model, bool isRequestNode)
        {
            string handleState = "4";
            if (isRequestNode)
            {
                handleState = "0";
            }
            string requestPerson = string.Empty;
            switch (model.FlowCode)
            {
                case "HolidayRequest":
                    HolidayRequestView holidayRequestView = HolidayRequestService.GetHolidayRequestByID(model.RecordID);
                    requestPerson = holidayRequestView.RequestPerson;
                    HolidayRequestService.UpdateHoliday(Guid.Parse(model.RecordID), "", DateTime.Now, DateTime.Now, handleState, true);
                    break;
                case "Alter":
                    AlterView alterView = AlterService.GetAlterByID(model.RecordID);
                    requestPerson = alterView.RequestPerson;
                    alterView.HandleState = handleState;
                    AlterService.SaveAlter(alterView);
                    break;
            }
            return requestPerson;
        }

        /// <summary>
        /// 添加已办、删除待办
        /// </summary>
        /// <param name="model">流转视图的Model</param>
        /// <param name="approvalOpinion">回退意见</param>
        /// <param name="currentFlowNodeView">当前节点</param>
        private void ProcessCurrentNodeForBack(FlowRecordView model, string approvalOpinion, FlowNodeView currentFlowNodeView)
        {
            List<ProcessedTaskView> addProcessedTaskList = new List<ProcessedTaskView>();
            List<BaklogTaskView> deleteBaklogTaskNewList = new List<BaklogTaskView>();
            List<BaklogTaskView> originalBaklogTaskList = BaklogTaskService.GetBaklogTaskByRecordID(model.RecordID);
            foreach (BaklogTaskView baklogTaskView in originalBaklogTaskList)
            {
                if (baklogTaskView.NodeLevel == currentFlowNodeView.NodeLevel)
                {
                    deleteBaklogTaskNewList.Add(baklogTaskView);
                    if (baklogTaskView.CurrentProcessPerson == User.Identity.Name)
                    {
                        addProcessedTaskList.Add(new ProcessedTaskView()
                        {
                            ID = Guid.NewGuid(),
                            RecordID = model.RecordID,
                            CurrentProcessNodeCode = model.CurrentFlowNodeCode,
                            CurrentProcessNodeName = currentFlowNodeView.NodeName,
                            ApprovalOpinion = approvalOpinion,
                            CurrentProcessPersonDepartment = baklogTaskView.CurrentProcessPersonDepartment,
                            CurrentProcessPerson = baklogTaskView.CurrentProcessPerson,
                            ProcessTime = DateTime.Now,
                            HandleState = "4"
                        });
                    }
                }
            }
            ProcessedTaskService.AddProcessedTask(addProcessedTaskList);
            BaklogTaskService.DeleteBaklogTask(deleteBaklogTaskNewList);
        }

        /// <summary>
        /// 添加回退待办
        /// </summary>
        /// <param name="selectBackNodeList">回退节点信息</param>
        /// <param name="model">流转视图的Model</param>
        /// <param name="requestPerson">申请人</param>
        /// <param name="backNodeCode">回退节点</param>
        private void AddBaklogTaskForBack(bool isRequestNode, XmlNodeList selectBackNodeList, FlowRecordView model, string requestPerson, string backNodeCode)
        {
            if (!isRequestNode)
            {
                List<BaklogTaskView> addList = new List<BaklogTaskView>();
                string[] processDepartmentAndPersonArr = selectBackNodeList[0].SelectSingleNode("NodeProcessDepartmentPerson").InnerText.Split(',');
                foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
                {
                    string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');
                    BaklogTaskView add = new BaklogTaskView();
                    add.ID = GuidHelper.NewGuid();
                    add.RecordID = model.RecordID;
                    switch (model.FlowCode)
                    {
                        case "HolidayRequest":
                            add.TaskName = "请假单";
                            break;
                        case "Alter":
                            add.TaskName = "过程管理";
                            break;
                    }
                    add.TaskType = model.FlowCode;
                    add.RequestPerson = requestPerson;
                    add.CurrentFlowNodeCode = backNodeCode;
                    add.CurrentProcessPersonDepartment = subProcessDepartmentAndPersonArr[0];
                    add.CurrentProcessPerson = subProcessDepartmentAndPersonArr[1];
                    add.NodeLevel = Convert.ToInt32(selectBackNodeList[0].SelectSingleNode("NodeLevel").InnerText);
                    addList.Add(add);
                }
                BaklogTaskService.AddBaklogTask(addList);
            }
        }

        private int AddFlowProcessMessage(List<CompleteFlowNodeView> backPassCodeList, string flowCode, string backNodeCode)
        {
            int actionType = 1;
            if (backPassCodeList.Count > 1)
            {
                //发回退消息
                List<FlowProcessMessageView> flowProcessMessageAddViewList = new List<FlowProcessMessageView>();
                foreach (CompleteFlowNodeView completeFlowNodeView in backPassCodeList)
                {
                    if (completeFlowNodeView.NodeCode != backNodeCode)
                    {
                        string[] processDepartmentAndPersonArr = completeFlowNodeView.NodeProcessDepartmentPerson.Split(',');
                        foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
                        {
                            string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');
                            flowProcessMessageAddViewList.Add(new FlowProcessMessageView()
                            {
                                ID = GuidHelper.NewGuid(),
                                RecordID = completeFlowNodeView.RecordID,
                                FlowCode = flowCode,
                                FlowNodeCode = completeFlowNodeView.NodeCode,
                                ProcessUserDepartment = subProcessDepartmentAndPersonArr[0],
                                ProcessUser = subProcessDepartmentAndPersonArr[1],
                                SponsorUser = User.Identity.Name,
                                ProcessType = "4",
                                LastUpdateUser = User.Identity.Name
                            });
                        }
                    }
                }
                FlowProcessMessageService.AddFlowProcessMessage(flowProcessMessageAddViewList);
                actionType = 2;
            }
            return actionType;
        }

        private void AddBackPath(string preNodeCodeStr, List<CompleteFlowNodeView> backPassCodeList, List<BackPath> lstBackPath, string nodeCode)
        {
            if (!string.IsNullOrEmpty(preNodeCodeStr))
            {
                string[] preNodeCodeArr = preNodeCodeStr.Split(',');
                foreach (string preNodeCode in preNodeCodeArr)
                {
                    CompleteFlowNodeView selectCompleteFlowNodeView = backPassCodeList.SingleOrDefault(b => b.NodeCode == preNodeCode);
                    if (selectCompleteFlowNodeView != null)
                    {
                        lstBackPath.Add(new BackPath() { PathStartNodeCode = selectCompleteFlowNodeView.NodeCode, PathEndNodeCode = nodeCode, OrderNo = lstBackPath.Count + 1, NodeType = selectCompleteFlowNodeView.NodeType });
                        AddBackPath(selectCompleteFlowNodeView.PreNodeCode, backPassCodeList, lstBackPath, selectCompleteFlowNodeView.NodeCode);
                    }
                }
            }
        }

        private void AddSubDeleteCompleteFlowNode(FlowRecordView model, string parentNodeCode, List<CompleteFlowNodeView> deleteCompleteFlowNodeViewList,ref string flowCodeStr)
        {
            List<CompleteFlowNodeView> subCompleteFlowNodeViewList = CompleteFlowNodeService.GetCompleteFlowNodeByParentNodeCode(model.RecordID, parentNodeCode, false,true);
            foreach (CompleteFlowNodeView subCompleteFlowNodeView in subCompleteFlowNodeViewList)
            {
                if (!deleteCompleteFlowNodeViewList.Contains(subCompleteFlowNodeView))
                {
                    deleteCompleteFlowNodeViewList.Add(subCompleteFlowNodeView);
                    flowCodeStr +="'"+ subCompleteFlowNodeView.NodeCode + "',";
                }
                AddSubDeleteCompleteFlowNode(model, subCompleteFlowNodeView.NodeCode, deleteCompleteFlowNodeViewList, ref flowCodeStr);
            }
        }
        #endregion
    }

    //public class BackPath
    //{
    //    public string PathStartNodeCode { get; set; }

    //    public string PathEndNodeCode { get; set; }

    //    public int OrderNo { get; set; }

    //    public int NodeType { get; set; }
    //}
}